package com.egao.common.module.student.service.impl;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.egao.common.core.exception.BusinessException;
import com.egao.common.core.utils.CoreUtil;
import com.egao.common.core.utils.ExcelUtils;
import com.egao.common.core.web.JsonResult;
import com.egao.common.core.web.PageParam;
import com.egao.common.module.student.constants.StudentPovertyConstants;
import com.egao.common.module.student.entity.Student;
import com.egao.common.module.student.entity.StudentPoverty;
import com.egao.common.module.student.entity.excel.StudentPovertyExcel;
import com.egao.common.module.student.mapper.StudentPovertyMapper;
import com.egao.common.module.student.service.StudentPovertyService;
import com.egao.common.module.student.service.StudentService;
import com.egao.common.module.system.constants.DictConstants;
import com.egao.common.module.system.entity.Dict;
import com.egao.common.module.system.service.DictService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.util.*;

/**
 * 学生贫困信息接口实现类
 * @author lym
 */
@Service
public class StudentPovertyServiceImpl extends ServiceImpl<StudentPovertyMapper, StudentPoverty> implements StudentPovertyService {

    @Autowired
    private DictService dictService;
    @Autowired
    private StudentService studentService;

    private final Logger logger = LoggerFactory.getLogger(StudentServiceImpl.class.getName());

    @Override
    public List<StudentPoverty> listPage(PageParam<StudentPoverty> page) {
        return baseMapper.listPage(page);
    }

    @Override
    public JsonResult detail(Integer id) {
        Map<String, List<Dict>> dictMaps = dictService.cacheMaps(StudentPovertyConstants.FORM_DICT_TYPES);
        return JsonResult.ok().setData(baseMapper.detail(id)).put("dictMaps", dictMaps);
    }

    @Override
    public JsonResult updateStudentPoverty(StudentPoverty studentPoverty, Integer loginUserId) {
        if (studentPoverty == null) {
            throw new BusinessException("信息异常");
        }

        if (studentPoverty.getId() == null) {
            throw new BusinessException("信息键值异常");
        }

        if (studentPoverty.getCreateBy() == null) {
            studentPoverty.setCreateBy(loginUserId);
        }

        studentPoverty.setUpdateBy(loginUserId);
//        studentPoverty.setFill(StudentPovertyConstants.FILL_TRUE);

        if (baseMapper.updateById(studentPoverty) > 0) {
            return JsonResult.ok("保存成功");
        }

        return JsonResult.error("保存失败");
    }

    @Override
    public JsonResult submitStudentPoverty(StudentPoverty studentPoverty, Integer loginUserId) {
        if (studentPoverty == null) {
            throw new BusinessException("信息异常");
        }

        if (studentPoverty.getId() == null) {
            throw new BusinessException("信息键值异常");
        }

        if (studentPoverty.getCreateBy() == null) {
            studentPoverty.setCreateBy(loginUserId);
        }

        studentPoverty.setUpdateBy(loginUserId);
        studentPoverty.setFill(StudentPovertyConstants.FILL_TRUE);

        if (baseMapper.updateById(studentPoverty) > 0) {
            return JsonResult.ok("提交成功");
        }

        return JsonResult.error("提交失败");
    }

    @Override
    public JsonResult importExcel(MultipartFile file, String category, Integer loginUserId) {
        if (StrUtil.isBlank(category)) {
            return JsonResult.error("类型参数异常");
        }

        StringBuilder sb = new StringBuilder();
        try {
            // 读取Excel
            int startRow = 1;
            ExcelReader reader = ExcelUtil.getReader(file.getInputStream(), 0);
            List<List<Object>> list = reader.read(startRow);

            // 进行非空和重复检查
            sb.append(CoreUtil.excelCheckBlank(list, startRow, 0));
            sb.append(CoreUtil.excelCheckRepeat(list, startRow, 0));
            if (!sb.toString().isEmpty()) {
                return JsonResult.error(sb.toString());
            }

            // 进行数据库层面检查
            List<StudentPoverty> studentPovertyList = new ArrayList<>();
            for (int i = 0; i < list.size(); i++) {
                List<Object> objects = list.get(i);
                String xh = String.valueOf(objects.get(0));

                Student student = studentService.getByXh(xh);

                if (student == null) {
                    sb.append("第");
                    sb.append(i + startRow + 1);
                    sb.append("行第1");
                    sb.append("列学号不存在;\r\n");
                } else {
                    StudentPoverty studentPoverty = new StudentPoverty();
                    studentPoverty.setCategory(category);
                    studentPoverty.setStudentId(student.getId());
                    studentPoverty.setFill(StudentPovertyConstants.FILL_FALSE);
                    studentPoverty.setCreateBy(loginUserId);

                    int count = baseMapper.selectCount(new QueryWrapper<StudentPoverty>()
                    .eq("student_id", student.getId())
                            .eq("category", category)
                    );

                    if (count == 0) {
                        studentPovertyList.add(studentPoverty);
                    }
                }

            }

            if (!sb.toString().isEmpty()) {
                return JsonResult.error(sb.toString());
            }

            int okNum = 0, errorNum = 0;
            for (StudentPoverty studentPoverty : studentPovertyList) {
                if (baseMapper.insert(studentPoverty) > 0) {
                    okNum++;
                } else {
                    errorNum++;
                }
            }
            return JsonResult.ok("导入完成，成功" + okNum + "条，失败" + errorNum + "条");
        } catch (IOException e) {
            e.printStackTrace();
        }

        return JsonResult.error("导入失败");
    }

    @Override
    public void exportExcel(Map<String, Object> page, HttpServletResponse response) {

        List<StudentPovertyExcel> list = baseMapper.listExcel(page);

        for (StudentPovertyExcel item : list) {
            item.setSchoolName("10520");
            item.setXb(dictService.cacheLabel(DictConstants.TYPE_XB, item.getXb()));
            item.setXl(dictService.cacheLabel(DictConstants.TYPE_XL, item.getXl()));
            item.setSyszd(dictService.cacheLabel(DictConstants.TYPE_SYSZD, item.getSyszd()));
            item.setPovertyType(dictService.cacheLabel(DictConstants.POVERTY_TYPE, item.getPovertyType()));
            item.setHelpType(dictService.cacheLabel(DictConstants.HELP_TYPE, item.getHelpType()));
            item.setIntenType(dictService.cacheLabel(DictConstants.POVERTY_INTEN_TYPE, item.getIntenType()));
            item.setIntenArea(dictService.cacheLabel(DictConstants.TYPE_SYSZD, item.getIntenArea()));
            item.setIntenIndustry(dictService.cacheLabel(DictConstants.COMPANY_INDUSTRY, item.getIntenIndustry()));
            item.setIntenJobCategory(dictService.cacheLabel(DictConstants.TYPE_YXZWLB, item.getIntenJobCategory()));
            item.setCompanyOneArea(dictService.cacheLabel(DictConstants.TYPE_SYSZD, item.getCompanyOneArea()));
            item.setCompanyOneJoin(dictService.cacheLabel(DictConstants.WHETHER, item.getCompanyOneJoin()));
            item.setCompanyOneTime(DateUtil.formatDate(DateUtil.parse(item.getCompanyOneTime())));
            item.setCompanySecondArea(dictService.cacheLabel(DictConstants.TYPE_SYSZD, item.getCompanySecondArea()));
            item.setCompanySecondJoin(dictService.cacheLabel(DictConstants.WHETHER, item.getCompanySecondJoin()));
            item.setCompanySecondTime(DateUtil.formatDate(DateUtil.parse(item.getCompanySecondTime())));
            item.setCompanyThirdArea(dictService.cacheLabel(DictConstants.TYPE_SYSZD, item.getCompanyThirdArea()));
            item.setCompanyThirdJoin(dictService.cacheLabel(DictConstants.WHETHER, item.getCompanyThirdJoin()));
            item.setCompanyThirdTime(DateUtil.formatDate(DateUtil.parse(item.getCompanyThirdTime())));
            item.setFinallyJobType(dictService.cacheLabel(DictConstants.POVERTY_INTEN_TYPE, item.getXb()));
            item.setFill("0".equals(item.getFill()) ? "已填报" : "未填报");
        }

        ExcelWriter writer = ExcelUtil.getWriter(true);

        excelAddHeaderAlias(writer);

        writer.write(list, true);

        // 设置列自适应宽 必须在write以后
        ExcelUtils.autoColumnMaxSizeAll(writer.getSheet());

        String fileName = "student-" + DateUtil.format(new Date(), DatePattern.PURE_DATE_PATTERN) + ".xlsx";

        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        response.setHeader("Content-Disposition","attachment;filename=" + fileName);

        try {
            OutputStream out = response.getOutputStream();
            writer.flush(out, true);
            writer.close();
            IoUtil.close(out);
        } catch (IOException e) {
            writer.close();
            logger.error("导出失败 - StudentPovertyServiceImpl - exportExcel", e);
        } finally {
            writer.close();
        }

    }

    /**
     * 为导出对象设置别名和排序 排序顺序为add顺序
     * @param writer ExcelWriter
     */
    public void excelAddHeaderAlias(ExcelWriter writer) {
        writer.addHeaderAlias("schoolName", "学校");
        writer.addHeaderAlias("collegeName", "学院");
        writer.addHeaderAlias("majorName", "专业");
        writer.addHeaderAlias("xh", "学号");
        writer.addHeaderAlias("xm", "姓名");
        writer.addHeaderAlias("xb", "性别");
        writer.addHeaderAlias("xl", "学历");
        writer.addHeaderAlias("sfzhm", "身份证号码");
        writer.addHeaderAlias("ksh", "考生号");
        writer.addHeaderAlias("syszd", "生源地区");
        writer.addHeaderAlias("mobile", "联系方式");
        writer.addHeaderAlias("homeName", "家庭联系人姓名");
        writer.addHeaderAlias("povertyType", "贫困状况");
        writer.addHeaderAlias("helpType", "帮扶状况");
        writer.addHeaderAlias("helpMeasures", "帮扶措施");
        writer.addHeaderAlias("homeMobile", "家庭电话");
        writer.addHeaderAlias("schoolTeacher", "学校帮扶责任人");
        writer.addHeaderAlias("schoolTeacherPosition", "职务");
        writer.addHeaderAlias("schoolTeacherMobile", "帮扶人电话");
        writer.addHeaderAlias("intenType", "意向类别");
        writer.addHeaderAlias("intenArea", "意向地区");
        writer.addHeaderAlias("intenIndustry", "意向单位行业");
        writer.addHeaderAlias("intenJobCategory", "意向职位类别");
        writer.addHeaderAlias("companyOne", "学校推荐单位1");
        writer.addHeaderAlias("companyOneArea", "学校推荐单位1所在地");
        writer.addHeaderAlias("companyOnePosition", "单位1岗位名称");
        writer.addHeaderAlias("companyOneJoin", "是否在单位1就业");
        writer.addHeaderAlias("companyOneTime", "推荐单位1时间");
        writer.addHeaderAlias("companyOneExit", "不去单位1就业原因");
        writer.addHeaderAlias("companySecond", "学校推荐单位2");
        writer.addHeaderAlias("companySecondArea", "学校推荐单位2所在地");
        writer.addHeaderAlias("companySecondPosition", "单位2岗位名称");
        writer.addHeaderAlias("companySecondJoin", "是否在单位2就业");
        writer.addHeaderAlias("companySecondTime", "推荐单位2时间");
        writer.addHeaderAlias("companySecondExit", "不去单位2就业原因");
        writer.addHeaderAlias("companyThird", "学校推荐单位3");
        writer.addHeaderAlias("companyThirdArea", "学校推荐单位3所在地");
        writer.addHeaderAlias("companyThirdPosition", "单位3岗位名称");
        writer.addHeaderAlias("companyThirdJoin", "是否在单位3就业");
        writer.addHeaderAlias("companyThirdTime", "推荐单位3时间");
        writer.addHeaderAlias("companyThirdExit", "不去单位3就业原因");
        writer.addHeaderAlias("finallyJobType", "最终就业类型");
        writer.addHeaderAlias("finallyJobWhere", "最终确定的就业去向");
        writer.addHeaderAlias("noJobReason", "暂不就业理由");
        writer.addHeaderAlias("fill", "是否填报");
    }
}
